import * as Blockly from 'blockly/core';
import { JavascriptGenerator, javascriptGenerator } from "blockly/javascript";
import { Tanslate } from './translate';
import { getValue } from './com';
import { WorkspaceSvg } from 'blockly/core';
export namespace Medias {
    const blocks = [
        {
            'key': 'media_audio',
            'message0': '%{media_audio}',
            'output': 'audio',
            'colour': 290
        },
        {
            'key': 'media_audio_funcs',
            'message0': '%1 %{from} %2 %3',
            'args0': [
                {
                    'type': 'input_value',
                    'name': 'TARGET',
                    'check': 'audio',
                },
                {
                    'type': 'input_value',
                    'name': 'VALUE',
                    'check': ['stream', 'element'],
                },
                {
                    'type': 'field_dropdown',
                    'name': 'FUNC',
                    'options': [
                        ['%{media_audio_create_stream}', 'createMediaStreamSource'],
                        ['%{media_audio_create_el_source}', 'createMediaElementSource'],
                    ],
                },
            ],
            "inputsInline": true,
            'output': 'audio_source',
            'colour': 290
        },
        {
            'key': 'media_audio_close',
            'message0': '%1 %{media_audio_close}',
            "args0": [
                {
                    'type': 'input_value',
                    'name': 'TARGET',
                    'check': 'audio',
                },
            ],
            "nextStatement": null,
            "previousStatement": null,
            'colour': 290
        },
        {
            'key': 'media_audio_connect',
            'message0': '%1 %{media_audio_connect} %2',
            "args0": [
                {
                    'type': 'input_value',
                    'name': 'SOURCE',
                    'check': 'audio_source',
                },
                {
                    'type': 'input_value',
                    'name': 'TARGET',
                    'check': 'audio',
                },
            ],
            "inputsInline": true,
            "nextStatement": null,
            "previousStatement": null,
            'colour': 290
        },
        {
            'key': 'get_user_media',
            'message0': '%{get_user_media} %{media_audio} %1 %{media_video} %2 \n',
            "args0": [
                {
                    'type': 'field_checkbox',
                    'name': 'AUDIO',
                    "checked": true
                },
                {
                    'type': 'field_checkbox',
                    'name': 'VIDEO',
                    "checked": true
                },
            ],
            "message1": '%{media_video_width} %1 %{media_video_height} %2',
            "args1": [
                {
                    'type': 'field_number',
                    'name': 'WIDTH',
                    'value': 1280,
                },
                {
                    'type': 'field_number',
                    'name': 'HEIGHT',
                    'value': 720,
                },
            ],
            "inputsInline": true,
            "output": 'Promise',
            'colour': 310
        },
        {
            'key': 'get_user_media_with_id',
            'message0': '%{get_user_media} %{get_user_media_streamId} %1',
            "args0": [
                {
                    'type': 'input_value',
                    'name': 'ID',
                    "check": ['String', 'Number']
                },
            ],
            "inputsInline": true,
            "output": 'Promise',
            'colour': 310
        },
        {
            'key': 'media_recorder',
            'message0': '%{from} %1 %{media_recorder} %{media_recorder_and_setup}\n',
            "args0": [
                {
                    'type': 'input_value',
                    'name': 'STREAM',
                    "check": 'stream'
                },
            ],
            "message1": '%{media_recorder_type} %1 %{media_recorder_audio_bitrate} %2 %{media_recorder_video_bitrate} %3',
            "args1": [
                {
                    'type': 'field_dropdown',
                    'name': 'MIME_TYPE',
                    'options': [
                        ['mp4', 'video/mp4'],
                        ['webm', 'video/webm'],
                        ['ogg', 'video/ogg'],
                        ['mp3', 'audio/mpeg'],
                        ['wav', 'audio/wav'],
                        ['ogg', 'audio/ogg'],
                    ]
                },
                {
                    'type': 'field_number',
                    'name': 'AUDIO_BITRATE',
                    'value': 128000,
                },
                {
                    'type': 'field_number',
                    'name': 'VIDEO_BITRATE',
                    'value': 2500000,
                }
            ],
            "output": 'MediaRecorder',
            'colour': 290
        },
        {
            'key': 'media_recorder_funcs',
            'message0': '%1 %2',
            "args0": [
                {
                    'type': 'input_value',
                    'name': 'TARGET',
                    'check': 'MediaRecorder',
                },
                {
                    'type': 'field_dropdown',
                    'name': 'FUNC',
                    'options': [
                        ['%{media_recorder_start}', 'start'],
                        ['%{media_recorder_stop}', 'stop'],
                        ['%{media_recorder_pause}', 'pause'],
                        ['%{media_recorder_resume}', 'resume'],
                    ],
                },
            ],
            "inputsInline": true,
            "nextStatement": null,
            "previousStatement": null,
            'colour': 290
        },
        {
            'key': 'media_recorder_events',
            'message0': '%{when} %1 %2 %{element_event_args} %3',
            "args0": [
                {
                    'type': 'input_value',
                    'name': 'TARGET',
                    'check': 'MediaRecorder',
                },
                {
                    'type': 'field_dropdown',
                    'name': 'EVENT',
                    'options': [
                        ['%{media_recorder_dataavailable}', 'dataavailable'],
                        ['%{media_recorder_event_stop}', 'stop'],
                        ['%{media_recorder_event_error}', 'error'],
                        ['%{media_recorder_event_pause}', 'pause'],
                        ['%{media_recorder_event_resume}', 'resume'],
                        ['%{media_recorder_event_start}', 'start'],
                    ],
                },
                {
                    "type": "field_variable",
                    "name": "ARG",
                    "check": "String",
                    "variable": "event"
                },
            ],
            "message1": "%{do} %1",
            "args1": [
                {
                    'type': 'input_statement',
                    'name': 'BODY0',
                },
            ],
            "inputsInline": true,
            "nextStatement": null,
            "previousStatement": null,
            'colour': 290
        },
        
    ]

    export function init() {
        initGenerator()
        Tanslate.tr(blocks).forEach((item: any) => {
            Blockly.Blocks[item.key] = {
                init: function (this: Blockly.Block) {
                    this.jsonInit(item);
                    if (item.key === 'controls_flow_statements') {
                        this.setOnChange((e) => {
                            const ws = this.workspace as WorkspaceSvg;
                            if (
                                !ws.isDragging ||
                                ws.isDragging() ||
                                (e.type !== Blockly.Events.BLOCK_MOVE && e.type !== Blockly.Events.BLOCK_CREATE)
                            ) {
                                return;
                            }
                            this.setWarningText(
                                Blockly.Msg['CONTROLS_FLOW_STATEMENTS_WARNING'],
                            );
                        })
                    }
                }
            }
        })
    }

    export function getTools() {
        const netBlocks = {
            kind: 'category',
            name: Blockly.Msg['medias'],
            'colour': 290,
            contents: [] as any[]
        }
        blocks.forEach((item: any) => {
            netBlocks.contents.push({
                kind: 'block',
                type: item.key
            })
        })

        return netBlocks
    }

    function initGenerator() {

        javascriptGenerator.forBlock['media_audio'] = function () {
            return `(new AudioContext())`;
        }

        javascriptGenerator.forBlock['media_audio_funcs'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const TARGET = getValue(block, generator, 'TARGET')
            const VALUE = getValue(block, generator, 'VALUE')
            const FUNC = getValue(block, generator, 'FUNC')
            if (!TARGET || !VALUE || !FUNC) {
                throw new Error(block.id);
            }
            return `${TARGET}.${FUNC}(${VALUE})`;
        }

        javascriptGenerator.forBlock['media_audio_close'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const TARGET = getValue(block, generator, 'TARGET')
            if (!TARGET) {
                throw new Error(block.id);
            }
            return `${TARGET}.close();`;
        }

        javascriptGenerator.forBlock['media_audio_connect'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const TARGET = getValue(block, generator, 'TARGET')
            const SOURCE = getValue(block, generator, 'SOURCE')
            if (!TARGET || !SOURCE) {
                throw new Error(block.id);
            }
            return `${SOURCE}.connect(${TARGET}.destination);`;
        }

        javascriptGenerator.forBlock['get_user_media'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const AUDIO = getValue(block, generator, 'AUDIO')
            const VIDEO = getValue(block, generator, 'VIDEO')
            const WIDTH = getValue(block, generator, 'WIDTH')
            const HEIGHT = getValue(block, generator, 'HEIGHT')
            if (!AUDIO || !VIDEO || !WIDTH || !HEIGHT) {
                throw new Error(block.id);
            }
            if (VIDEO !== 'TRUE') {
                return `navigator.mediaDevices.getUserMedia({audio: ${AUDIO==='TRUE'}})`;
            }
            return `navigator.mediaDevices.getUserMedia({audio: ${AUDIO === 'TRUE'}, video: {width: ${WIDTH}, height: ${HEIGHT}}})`;
        }

        javascriptGenerator.forBlock['get_user_media_with_id'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const ID = getValue(block, generator, 'ID')
            if (!ID) {
                throw new Error(block.id);
            }
            return `navigator.mediaDevices.getUserMedia({video: {mandatory: {chromeMediaSource: "desktop",chromeMediaSourceId: ${ID}}}})`;
        }

        javascriptGenerator.forBlock['media_recorder'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const STREAM = getValue(block, generator, 'STREAM')
            const MIME_TYPE = getValue(block, generator, 'MIME_TYPE')
            const AUDIO_BITRATE = getValue(block, generator, 'AUDIO_BITRATE')
            const VIDEO_BITRATE = getValue(block, generator, 'VIDEO_BITRATE')
            if (!STREAM || !MIME_TYPE || !AUDIO_BITRATE || !VIDEO_BITRATE) {
                throw new Error(block.id);
            }
            return `new MediaRecorder(${STREAM}, {mimeType: '${MIME_TYPE}', audioBitsPerSecond: ${AUDIO_BITRATE}, videoBitsPerSecond: ${VIDEO_BITRATE}})`;
        }

        javascriptGenerator.forBlock['media_recorder_funcs'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const TARGET = getValue(block, generator, 'TARGET')
            const FUNC = getValue(block, generator, 'FUNC')
            if (!TARGET || !FUNC) {
                throw new Error(block.id);
            }
            return `${TARGET}.${FUNC}();\n`;
        }

        javascriptGenerator.forBlock['media_recorder_events'] = function (block: Blockly.Block, generator: JavascriptGenerator) {
            const TARGET = getValue(block, generator, 'TARGET')
            const EVENT = getValue(block, generator, 'EVENT')
            const ARG = getValue(block, generator, 'ARG')
            if (!TARGET || !EVENT || !ARG) {
                throw new Error(block.id);
            }
            let BODY0 = block.getInputTargetBlock('BODY0');
            let lines = ''
            if (BODY0) {
                const line = generator.blockToCode(BODY0)
                lines = (typeof line === 'string' ? line : line.join('\n'))
            }
            return `${TARGET}.on${EVENT} = async (${ARG})=>{\n${lines}\n};`;
        }
    }
}